/**
 * This file is part of the dspace-poltman project http://www.poltman.com.
 *
 * This is free software; you can redistribute it and/or modify it under
 * the terms of DuraSpace DSpace license detailed in the LICENSE and NOTICE 
 * files at the root of the source tree and available online at
 * http://www.dspace.org/license/
 * 
 */


package com.poltman.dscentral.communities;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.dao.DataAccessException;
import org.zkoss.zkplus.spring.SpringUtil;
import org.zkoss.zul.AbstractTreeModel;
import org.zkoss.zul.Messagebox;
import org.zkoss.zul.ext.TreeSelectableModel;

import com.poltman.dscentral.db.entity.dspace.Community2CommunityEntity;
import com.poltman.dscentral.db.entity.dspace.CommunityEntity;
import com.poltman.dscentral.db.service.dspace.Community2CommunityService;
import com.poltman.dscentral.db.service.dspace.CommunityService;


/* ------------------- communities first level -------------------- 

select * from community c where c.community_id not in (select child_comm_id from community2community);

------------------------------------------------------------------*/

/**
 * 
 * @author Zbigniew Ciok; z.ciok@poltman.com
 *
 */
public class CommunityTreeModel extends AbstractTreeModel<Integer> implements TreeSelectableModel, Serializable {

	private static final long serialVersionUID = 7822729366554623684L;
	
	private static Logger log = Logger.getLogger(CommunityTreeModel.class);
	
	private ArrayList<Integer> firstLevel = null;
	
	//TODO
	//@Autowired
	private Community2CommunityService community2CommunityService;
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public CommunityTreeModel() throws Exception {
		//TODO: BigList
		this(new ArrayList(new BigList(4)));
	}
	/**
	 * Constructor
	 * 
	 * @param tree
	 *            the list is contained all data of nodes.
	 */
	public CommunityTreeModel(ArrayList<Integer> tree) {
		super(tree.get(0));
		this.firstLevel();
		community2CommunityService = (Community2CommunityService) SpringUtil.getBean("community2CommunityService");
		if (community2CommunityService == null) {
			log.error("community2CommunityService == null");
			Messagebox.show("Failed to access community2CommunityService", "DSCentral Error", 0,  Messagebox.ERROR);
		}
	}
	
	/**
	 * 
	 * @throws Exception
	 */
	private void firstLevel() {
		firstLevel = new ArrayList<Integer>();
		try {
			CommunityService  communityService = (CommunityService) SpringUtil.getBean("communityService");
			if (communityService == null) {
				log.error("CommunityTreeModel.firstLevel; communityService == null");
				throw new Exception("ERROR: CommunityTreeModel.firstLevel; communityService == null");
			} else {
				List<CommunityEntity> communities = (List<CommunityEntity>) communityService.findFirstLevelCommunities();
				for (int i = 0; i < communities.size(); i++) {
					firstLevel.add(communities.get(i).getCommunityId().intValue());
				}
			}
		} catch (Exception e) {
			log.error(e);
			Messagebox.show("Failed to access communityService", "DSCentral Error", 0,  Messagebox.ERROR);
		}
	}
	
	/**
	 * 
	 */
	@Override
	public Integer getChild(Integer parent, int index) {
		
		if (parent == 0) {
			if (index < firstLevel.size()) {
				return ((Integer)firstLevel.get(index));
			}
		} else {
			try {
				List<Community2CommunityEntity> childs = community2CommunityService.findByParentCommId(parent);
				return childs.get(index).getChildCommId().intValue();
			} catch (DataAccessException e) {
				log.error(e);
				Messagebox.show("getChild DataAccessException", "DSCentral Error", 0,  Messagebox.ERROR);
			} catch (Exception e) {
				log.error(e);
				Messagebox.show("getChild Exception", "DSCentral Error", 0,  Messagebox.ERROR);
			}
		}
		
		return null;
	}

	/**
	 * 
	 */
	@Override
	public int getChildCount(Integer parent) {
		int count = 0;
		
		if (parent == 0) { 
			return this.firstLevel.size();
		} else {
			try {
				List<Community2CommunityEntity> childs = community2CommunityService.findByParentCommId(parent);
				return childs.size();
			} catch (DataAccessException e) {
				log.error(e);
				Messagebox.show("getChildCount DataAccessException", "DSCentral Error", 0,  Messagebox.ERROR);
			} catch (Exception e) {
				log.error(e);
				Messagebox.show("getChildCount Exception", "DSCentral Error", 0,  Messagebox.ERROR);
			}
		}
		
		return count;
	}
	
	/**
	 * 
	 */
	@Override
	public boolean isLeaf(Integer node) {
		return (getChildCount(node) == 0);
	}

	/**
	 * 
	 */
	@Override
	public int getIndexOfChild(Integer arg0, Integer arg1) {
		return 0;
	}
}